﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Luminji.Core.Xaml.Common;
using System.Windows.Markup;
using System.Windows.Documents;
using System.Windows;

namespace Luminji.Core.Xaml
{
    /// <summary>
    /// 预定义数据格式类型
    /// </summary>
    public enum DataFormat
    {
        /// <summary>
        /// 未知(不确定)格式
        /// </summary>
        Null,
        /// <summary>
        /// 固定 (Text) 数据格式
        /// </summary>
        Fixed,
        /// <summary>
        /// ANSI编码 (Text) 数据格式
        /// </summary>
        Text,
        /// <summary>
        /// Rich Text Format (RTF) 数据格式
        /// </summary>
        Rtf,
        /// <summary>
        /// HyperText Mark-up Language (HTML) 数据格式
        /// </summary>
        Html,
        /// <summary>
        /// Extensible Application Markup Language (XAML) 数据格式
        /// </summary>
        Xaml
    }

    public class ExamXamlConverter
    {
        #region 检测一个字符串的数据格式

        /// <summary>
        /// 检测一个字符串的数据格式
        /// </summary>
        /// <param name="Content"></param>
        /// <returns></returns>
        public static DataFormat CheckDataFormat(string Content)
        {
            Content = Content.Trim();
            if (string.IsNullOrWhiteSpace(Content)) return DataFormat.Null;
            Regex RegExp = new Regex(@"(^<(?i)QuestionFlowDocument(.)*/>$)|(^<(?i)QuestionFlowDocument(.)*>([\s\S]*)</(?i)QuestionFlowDocument>$)");
            if (RegExp.IsMatch(Content)) return DataFormat.Xaml;
            RegExp = new Regex(@"([<](?i)p.*/>)|([<](?i)p.*>.*</p>)");
            if (RegExp.IsMatch(Content)) return DataFormat.Html;
            RegExp = new Regex(@"^\{\\rtf1\\[\s\S]*\}$");
            if (RegExp.IsMatch(Content)) return DataFormat.Rtf;
            RegExp = new Regex(@"(^[0,1]$)|(^([A-Z]((,[A-Z])?)+)$)");
            if (RegExp.IsMatch(Content)) return DataFormat.Fixed;
            return DataFormat.Text;
        }
        #endregion
        #region FlowDocument、Xaml、Html、Rtf
        /// <summary>
        /// 将“任意格式”转换为FlowDocument
        /// </summary>
        /// <param name="Content"></param>
        /// <returns></returns>
        public static QuestionFlowDocument ConvertToFlowDocument(string Content)
        {
            DataFormat DFormat = CheckDataFormat(Content);
            if (DFormat == DataFormat.Xaml) return XamlToFlowDocument(Content);
            else if (DFormat == DataFormat.Rtf) return RtfToFlowDocument(Content);
            else if (DFormat == DataFormat.Html) return HtmlToFlowDocument(Content);
            else if (DFormat == DataFormat.Text || DFormat == DataFormat.Fixed) return TextToFlowDocument(Content);
            return new QuestionFlowDocument();
        }
        /// <summary>
        /// 将“任意格式”转换为Xaml
        /// </summary>
        /// <param name="Content"></param>
        /// <returns></returns>
        public static string ConvertToXaml(string Content)
        {
            DataFormat DFormat = CheckDataFormat(Content);
            if (DFormat == DataFormat.Xaml || DFormat == DataFormat.Fixed)
                return Content;
            else if (DFormat == DataFormat.Rtf)
                return RtfToXaml(Content);
            else if (DFormat == DataFormat.Html)
                return HtmlToXaml(Content);
            else if (DFormat == DataFormat.Text)
                return TextToXaml(Content);
            return null;
        }
        /// <summary>
        /// 将“任意格式”转换为Rtf
        /// </summary>
        /// <param name="Content"></param>
        /// <returns></returns>
        public static string ConvertToRtf(string Content)
        {
            DataFormat DFormat = CheckDataFormat(Content);
            if (DFormat == DataFormat.Xaml)
                return XamlToRtf(Content);
            else if (DFormat == DataFormat.Rtf || DFormat == DataFormat.Fixed)
                return Content;
            else if (DFormat == DataFormat.Html)
                return HtmlToRtf(Content);
            else if (DFormat == DataFormat.Text)
                return TextToRtf(Content);
            return null;
        }
        /// <summary>
        /// 将“任意格式”转换为Html
        /// </summary>
        /// <param name="Content"></param>
        /// <returns></returns>
        public static string ConvertToHtml(string Content)
        {
            DataFormat DFormat = CheckDataFormat(Content);
            if (DFormat == DataFormat.Xaml)
                return XamlToHtml(Content);
            else if (DFormat == DataFormat.Rtf)
                return RtfToHtml(Content);
            else if (DFormat == DataFormat.Html || DFormat == DataFormat.Fixed)
                return Content;
            else if (DFormat == DataFormat.Text)
                return TextToHtml(Content);
            return null;
        }
        /// <summary>
        /// 将“任意格式”转换为Text
        /// </summary>
        /// <param name="Content"></param>
        /// <returns></returns>
        public static string ConvertToText(string Content)
        {
            DataFormat DFormat = CheckDataFormat(Content);
            if (DFormat == DataFormat.Xaml)
                return XamlToText(Content);
            else if (DFormat == DataFormat.Rtf)
                return RtfToText(Content);
            else if (DFormat == DataFormat.Html)
                return HtmlToText(Content);
            else if (DFormat == DataFormat.Text || DFormat == DataFormat.Fixed)
                return Content;
            return null;
        }
        /// <summary>
        /// 转换Xaml为FlowDocument
        /// </summary>
        /// <param name="Xaml"></param>
        /// <returns></returns>
        public static QuestionFlowDocument XamlToFlowDocument(string Xaml)
        {
            QuestionFlowDocument Qfd = new QuestionFlowDocument();
            if (string.IsNullOrEmpty(Xaml)) return Qfd;
            //System.IO.Packaging.PackUriHelper.Create(new Uri("pack://payload:,,wpf21847,/Xaml/Document.xaml"));
            var temp = XamlReader.Parse(Xaml);
            Qfd = temp as QuestionFlowDocument;
            return Qfd;
        }
        /// <summary>
        /// 转换FlowDocument为Xaml
        /// </summary>
        /// <param name="Qfd"></param>
        /// <returns></returns>
        public static string FlowDocumentToXaml(QuestionFlowDocument Qfd)
        {
            if (Qfd == null) return string.Empty;
            return System.Windows.Markup.XamlWriter.Save(Qfd);
        }
        /// <summary>
        /// 转换Rtf为FlowDocument
        /// </summary>
        /// <param name="Rtf"></param>
        /// <returns></returns>
        public static QuestionFlowDocument RtfToFlowDocument(string Rtf)
        {
            QuestionFlowDocument Qfd = new QuestionFlowDocument();
            if (string.IsNullOrEmpty(Rtf)) return Qfd;
            System.IO.MemoryStream Ms = null;
            System.IO.StreamWriter Sw = null;
            try
            {
                Ms = new System.IO.MemoryStream();
                Sw = new System.IO.StreamWriter(Ms);
                TextRange TRange = new TextRange(Qfd.ContentStart, Qfd.ContentEnd);
                Sw.Write(Rtf);
                Sw.Flush();
                Ms.Seek(0, System.IO.SeekOrigin.Begin);
                TRange.Load(Ms, DataFormats.Rtf);
            }
            catch { }
            finally
            {
                Sw.Dispose();
                Sw.Close();
                Ms.Dispose();
                Ms.Close();
            }
            return Qfd;
        }
        /// <summary>
        /// 转换FlowDocument为Rtf
        /// </summary>
        /// <param name="Qfd"></param>
        /// <returns></returns>
        public static string FlowDocumentToRtf(QuestionFlowDocument Qfd)
        {
            System.IO.MemoryStream Ms = null;
            System.IO.StreamReader Sr = null;
            try
            {
                Ms = new System.IO.MemoryStream();
                TextRange TRange = new TextRange(Qfd.ContentStart, Qfd.ContentEnd);
                TRange.Save(Ms, DataFormats.Rtf);
                Ms.Seek(0, System.IO.SeekOrigin.Begin);
                Sr = new System.IO.StreamReader(Ms);
                return Sr.ReadToEnd();
            }
            catch { }
            finally
            {
                Sr.Dispose();
                Sr.Close();
                Ms.Dispose();
                Ms.Close();
            }
            return string.Empty;
        }
        /// <summary>
        /// 转换Html为FlowDocument
        /// </summary>
        /// <param name="Html"></param>
        /// <returns></returns>
        public static QuestionFlowDocument HtmlToFlowDocument(string Html)
        {
            QuestionFlowDocument Qfd = XamlToFlowDocument(HtmlToXaml(Html));
            return Qfd;
        }
        /// <summary>
        /// 转换FlowDocument为Html
        /// </summary>
        /// <param name="Qfd"></param>
        /// <returns></returns>
        public static string FlowDocumentToHtml(QuestionFlowDocument Qfd)
        {
            return XamlToHtml(FlowDocumentToXaml(Qfd));
        }
        /// <summary>
        /// 转换Text为FlowDocument
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static QuestionFlowDocument TextToFlowDocument(string Text)
        {
            QuestionFlowDocument Qfd = new QuestionFlowDocument();
            if (string.IsNullOrEmpty(Text)) return Qfd;
            System.IO.MemoryStream Ms = null;
            System.IO.StreamWriter Sw = null;
            try
            {
                Ms = new System.IO.MemoryStream();
                Sw = new System.IO.StreamWriter(Ms);
                TextRange TRange = new TextRange(Qfd.ContentStart, Qfd.ContentEnd);
                Sw.Write(Text);
                Sw.Flush();
                Ms.Seek(0, System.IO.SeekOrigin.Begin);
                TRange.Load(Ms, DataFormats.Text);
            }
            catch { }
            finally
            {
                Sw.Dispose();
                Sw.Close();
                Ms.Dispose();
                Ms.Close();
            }
            return Qfd;
        }
        /// <summary>
        /// 转换FlowDocument为Text
        /// </summary>
        /// <param name="Qfd"></param>
        /// <returns></returns>
        public static string FlowDocumentToText(QuestionFlowDocument Qfd)
        {
            System.IO.MemoryStream Ms = null;
            System.IO.StreamReader Sr = null;
            try
            {
                Ms = new System.IO.MemoryStream();
                TextRange TRange = new TextRange(Qfd.ContentStart, Qfd.ContentEnd);
                TRange.Save(Ms, DataFormats.Text);
                Ms.Seek(0, System.IO.SeekOrigin.Begin);
                Sr = new System.IO.StreamReader(Ms);
                return Sr.ReadToEnd();
            }
            catch { }
            finally
            {
                Sr.Dispose();
                Sr.Close();
                Ms.Dispose();
                Ms.Close();
            }
            return string.Empty;
        }
        /// <summary>
        /// 转换Xaml为Rtf
        /// </summary>
        /// <param name="Xaml"></param>
        /// <returns></returns>
        public static string XamlToRtf(string Xaml)
        {
            return FlowDocumentToRtf(XamlToFlowDocument(Xaml));
        }
        /// <summary>
        /// 转换Xaml为Html
        /// </summary>
        /// <param name="Xaml"></param>
        /// <returns></returns>
        public static string XamlToHtml(string Xaml)
        {
            //original xaml have a bug, it have odd blank space
            if (string.IsNullOrEmpty(Xaml))
            {
                return "";
            }
            Xaml = Xaml.Replace("  ", " ");
            Xaml = Xaml.Replace(QuestionFlowDocument.DocumentEmptyXamlHeader, "<FlowDocument xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">");
            Xaml = Xaml.Replace(QuestionFlowDocument.DocumentEmptyXamlHeaderContainX, "<FlowDocument xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">");
            Xaml = Xaml.Replace(QuestionFlowDocument.DocumentEmptyXamlFoot, "</FlowDocument>");
            Xaml = Xaml.Replace("av:", "");
            return HtmlFromXamlConverter.ConvertXamlToHtml(Xaml, false);
        }
        /// <summary>
        /// 转换Xaml为Text
        /// </summary>
        /// <param name="Xaml"></param>
        /// <returns></returns>
        public static string XamlToText(string Xaml)
        {
            return FlowDocumentToText(XamlToFlowDocument(Xaml));
        }
        /// <summary>
        /// 转换Rtf为Xaml
        /// </summary>
        /// <param name="Rtf"></param>
        /// <returns></returns>
        public static string RtfToXaml(string Rtf)
        {
            return FlowDocumentToXaml(RtfToFlowDocument(Rtf));
        }
        /// <summary>
        /// 转换Rtf为Html
        /// </summary>
        /// <param name="Rtf"></param>
        /// <returns></returns>
        public static string RtfToHtml(string Rtf)
        {
            FlowDocument Fd = new FlowDocument();
            if (string.IsNullOrEmpty(Rtf)) return string.Empty;
            System.IO.MemoryStream Ms = null;
            System.IO.StreamWriter Sw = null;
            try
            {
                Ms = new System.IO.MemoryStream();
                Sw = new System.IO.StreamWriter(Ms);
                TextRange TRange = new TextRange(Fd.ContentStart, Fd.ContentEnd);
                Sw.Write(Rtf);
                Sw.Flush();
                Ms.Seek(0, System.IO.SeekOrigin.Begin);
                TRange.Load(Ms, DataFormats.Rtf);
            }
            catch (Exception) { }
            finally
            {
                Sw.Dispose();
                Sw.Close();
                Ms.Dispose();
                Ms.Close();
            }
            string Xaml = System.Windows.Markup.XamlWriter.Save(Fd);
            return HtmlFromXamlConverter.ConvertXamlToHtml(Xaml, false);
        }
        /// <summary>
        /// 转换Rtf为Text
        /// </summary>
        /// <param name="Xaml"></param>
        /// <returns></returns>
        public static string RtfToText(string Rtf)
        {
            return FlowDocumentToText(RtfToFlowDocument(Rtf));
        }
        /// <summary>
        /// 转换Html为Xaml
        /// </summary>
        /// <param name="Html"></param>
        /// <returns></returns>
        public static string HtmlToXaml(string Html)
        {
            string Xaml = HtmlToXamlConverter.ConvertHtmlToXaml(Html, true);
            Xaml = Xaml.Replace("<FlowDocument xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">", QuestionFlowDocument.DocumentEmptyXamlHeader);
            Xaml = Xaml.Replace("</FlowDocument>", QuestionFlowDocument.DocumentEmptyXamlFoot);
            Xaml = Xaml.Replace("<Paragraph", "<av:Paragraph");
            Xaml = Xaml.Replace("</Paragraph>", "</av:Paragraph>");
            Xaml = Xaml.Replace("<Run", "<av:Run");
            Xaml = Xaml.Replace("</Run>", "</av:Run>");
            Xaml = Xaml.Replace("<Span", "<av:Span");
            Xaml = Xaml.Replace("</Span>", "</av:Span>");
            Xaml = Xaml.Replace("<Image", "<av:Image");
            Xaml = Xaml.Replace("</Image>", "</av:Image>");
            return Xaml;
        }
        /// <summary>
        /// 转换Html为Rtf
        /// </summary>
        /// <param name="Html"></param>
        /// <returns></returns>
        public static string HtmlToRtf(string Html)
        {
            return XamlToRtf(HtmlToXaml(Html));
        }
        /// <summary>
        /// 转换Html为Text
        /// </summary>
        /// <param name="Xaml"></param>
        /// <returns></returns>
        public static string HtmlToText(string Html)
        {
            return FlowDocumentToText(HtmlToFlowDocument(Html));
        }
        /// <summary>
        /// 转换Text为Xaml
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string TextToXaml(string Text)
        {
            return QuestionFlowDocument.DocumentEmptyXamlHeader + "<av:Paragraph><av:Run xml:lang=\"zh-cn\">" + Text + "</av:Run></av:Paragraph>" + QuestionFlowDocument.DocumentEmptyXamlFoot;
        }
        /// <summary>
        /// 转换Text为Rtf
        /// </summary>
        /// <param name="Html"></param>
        /// <returns></returns>
        public static string TextToRtf(string Text)
        {
            return FlowDocumentToRtf(TextToFlowDocument(Text));
        }
        /// <summary>
        /// 转换Text为Html
        /// </summary>
        /// <param name="Html"></param>
        /// <returns></returns>
        public static string TextToHtml(string Text)
        {
            return string.Format("<p>{0}</p>", Text);
        }
        #endregion
    }
}
